<template>
	<view class="async-image-container" :style="{ width, height }">
		<!-- 加载中状态 - 显示CSS动画 -->
		<view v-if="status === 'loading'" class="image-placeholder background">
			<!-- From Uiverse.io by Mike11jr --> 
			<bs-load></bs-load>
		</view>

		<!-- 加载失败状态 -->
		<view v-else-if="status === 'error'" class="image-placeholder">
			<view class="spinner">
			<view class="dot"></view>
			<view class="dot"></view>
			<view class="dot"></view>
			<view class="dot"></view>
			<view class="dot"></view></view>
			<!-- <view class="error-icon">
				<view class="error-x"></view>
			</view> -->
			<!-- 点击重新加载 -->
			<!-- <view class="retry-btn" @tap.stop="reload">重新加载</view> -->
		</view>

		<!-- 加载成功状态 - 显示目标图片 -->
		<image class="target-image" :src="currentSrc" :mode="mode" @load="handleLoad" @error="handleError" alt="图片内容">
		</image>
	</view>
</template>

<script>
	export default {
		name: 'bs-img',
		props: {
			// 图片源地址
			src: {
				type: String,
				required: true
			},
			// 图片模式，同uniapp的image组件mode
			mode: {
				type: String,
				default: 'scaleToFill'
			},
			// 图片宽度
			width: {
				type: String,
				default: '100%'
			},
			// 图片高度
			height: {
				type: String,
				default: 'auto'
			},
			// 加载中动画颜色
			loadingColor: {
				type: String,
				default: '#409eff'
			},
			// 加载失败图标颜色
			errorColor: {
				type: String,
				default: '#f56c6c'
			}
		},
		data() {
			return {
				// 图片状态：loading/error/success
				status: 'loading',
				// 用于触发图片重新加载的变量
				currentSrc: this.src
			}
		},
		watch: {
			// 监听src变化，重新加载图片
			src(newVal) {
				this.status = 'loading';
				this.currentSrc = newVal;
			}
		},
		methods: {
			// 图片加载成功
			handleLoad() {
				this.status = 'success';
				// 触发成功回调
				this.$emit('load');
			},
			// 图片加载失败
			handleError() {
				this.status = 'error';
				// 触发失败回调
				this.$emit('error');
			},
			// 重新加载图片
			reload() {
				// 重置状态为加载中
				this.status = 'loading';
				// 通过修改src触发重新加载（添加时间戳避免缓存）
				this.currentSrc = this.src + (this.src.includes('?') ? '&' : '?') + Date.now();
			}
		}
	}
</script>

<style scoped lang="scss">
	.async-image-container {
		position: relative;
		overflow: hidden;
	}

	.image-placeholder {
		top: 0;
		left: 0;
		position: absolute;
		z-index: 1;
		width: 100%;
		height: 100%;
		display: flex;
		flex-direction: column;
		justify-content: center;
		align-items: center;
		/* background-color: #f5f5f5; */
	}

	/* 加载中动画 */
	

	

	/* 错误图标 */
	.error-icon {
		width: 40rpx;
		height: 40rpx;
		position: relative;
	}

	.error-x {
		position: absolute;
		width: 40rpx;
		height: 6rpx;
		background-color: v-bind(errorColor);
		border-radius: 3rpx;
		transform: rotate(45deg);
		top: 17rpx;
		left: 0;
	}

	.error-x::after {
		content: '';
		position: absolute;
		width: 40rpx;
		height: 6rpx;
		background-color: v-bind(errorColor);
		border-radius: 3rpx;
		transform: rotate(-90deg);
	}

	.retry-btn {
		margin-top: 16rpx;
		font-size: 24rpx;
		color: #666;
		cursor: pointer;
	}

	.target-image {
		top: 0;
		left: 0;
		position: absolute;
		width: 100%;
		height: 100%;
	}

	/* 旋转动画 */
	@keyframes spin {
		to {
			transform: rotate(360deg);
		}
	}

	/* 背景渐变和流动动画 */
	.background {
		width: 100%;
		height: 100%;
		background: linear-gradient(135deg,
				#ffffff,
				#f5f5f5,
				#e0e0e0,
				#d0d0d0);
		background-size: 400% 400%;
		animation: flow 10s ease infinite;
		display: flex;
		align-items: center;
		justify-content: center;
		position: relative;
	}

	@keyframes flow {
		0% {
			background-position: 0% 50%;
		}

		50% {
			background-position: 100% 50%;
		}

		100% {
			background-position: 0% 50%;
		}
	}
	
</style>